package MemoryManagement.Test;

import MemoryManagement.*;
import org.junit.jupiter.api.Test;

import java.util.ArrayList;

import static org.junit.jupiter.api.Assertions.*;

class PageTableTest {

    @Test
    void constructor_validInput_correctInitialization() {
        // Arrange
        byte[] table = new byte[Memory.pageSize];
        for (int i = 0; i < table.length; i += 8) {
            table[i] = 1; // 设置块号为1
            table[i + 1] = 1; // 设置状态为1
            table[i + 2] = 1; // 设置访问为1
            table[i + 3] = 1; // 设置修改为1
            table[i + 4] = 0; // 设置磁盘地址的高位为0
            table[i + 5] = 0; // 设置磁盘地址的次高位为0
            table[i + 6] = 0; // 设置磁盘地址的次低位为0
            table[i + 7] = 0; // 设置磁盘地址的低位为0
        }

        // Act
        PageTable pageTable = new PageTable(table);

        // Assert
        ArrayList<Item> items = pageTable.getPageTable();
        assertNotNull(items);
        assertEquals(Memory.pageSize / 8, items.size()); // 页表条目数应该与页面大小相符
        for (Item item : items) {
            assertEquals(1, item.getBlock());
            assertEquals(1, item.getState());
            assertEquals(1, item.getAccess());
            assertEquals(1, item.getChange());
            assertEquals(0, item.getDisk());
        }
    }

    @Test
    void constructor_invalidTableSize_throwIllegalArgumentException() {
        // Arrange
        byte[] invalidTable = new byte[Memory.pageSize - 1]; // 无效的表大小，不是 pageSize 的倍数

        // Act & Assert
        assertThrows(IllegalArgumentException.class, () -> new PageTable(invalidTable));
    }

    @Test
    void constructor_defaultConstructor_correctInitialization() {
        // Arrange & Act
        PageTable pageTable = new PageTable();

        // Assert
        ArrayList<Item> items = pageTable.getPageTable();
        assertNotNull(items);
        assertEquals(Memory.pageSize / 8, items.size()); // 页表条目数应该与页面大小相符
        // 检查每个条目是否正确初始化
        for (Item item : items) {
            assertEquals(0, item.getDisk());
            assertEquals(0, item.getState());
            assertEquals(0, item.getAccess());
            assertEquals(0, item.getChange());
            assertEquals(-1, item.getBlock());
        }
    }

    @Test
    void updatePageTable_validInput_pageTableUpdatedInMemory() {
        // Arrange

        ArrayList<Item> items = new ArrayList<>();
        // 假设有两个条目需要更新
        for (int i = 0; i < Memory.pageSize; i += 8) {
            items.add(new Item(i/8, 5, (byte) 1, (byte) 1, (byte) 1, (byte) 1));
        }
        System.out.println(items.size());


        // Act
        PageTable.UpdatePageTable(0, items);

        PageTable pageTable = new PageTable(Memory.readPage(0,0,Memory.pageSize));
        // Assert
        ArrayList<Item> updatedItems = pageTable.getPageTable();

        assertNotNull(updatedItems);
        assertEquals(Memory.pageSize / 8, updatedItems.size()); // 页表条目数应该与页面大小相符
        // 检查更新后的每个条目是否正确
        for (Item item : updatedItems) {
                assertEquals(5, item.getDisk());
                assertEquals(1, item.getState());
                assertEquals(1, item.getAccess());
                assertEquals(1, item.getChange());
                assertEquals(1, item.getBlock());
        }
    }
}
